/*
 * The program VMP functions as an adjuster
 * of VMs. It needs input of VM Matrix and
 * the topology info (Topo, Routing vari-
 * able like f_ij^st), and output the VM pl-
 * ace function VMP(VM_i)
*/

#include <iostream>
#include <stdio.h>
#include <string>
#include <sstream>
#include "VM.h"

using namespace std;

int main(int argc, char **argv)
{
	if (argc < 8)
	{
		cerr << "Invalid arguments, at least 8 needed\n";
		exit(1);
	}
	int i;
	string argus[7];
	/*argus[0] = "D:\\WORKSPACE\\SRC\\VMP\\vmp\\topo.in";
	argus[1] = "D:\\WORKSPACE\\SRC\\VMP\\vmp\\host.in";
	argus[2] = "D:\\WORKSPACE\\SRC\\VMP\\vmp\\vm.in";
	argus[3] = "1";
	argus[4] = "D:\\WORKSPACE\\SRC\\VMP\\vmp\\rand_place";
	argus[5] = "D:\\WORKSPACE\\SRC\\VMP\\vmp\\adjusted_place";
	argus[6] = "10";*/
	/*argus[0] = "H:\\Workspace\\VMP\\topo.in";
	argus[1] = "H:\\Workspace\\VMP\\host.in";
	argus[2] = "H:\\Workspace\\VMP\\vm.in";
	argus[3] = "1";
	argus[4] = "H:\\Workspace\\VMP\\rand_place";
	argus[5] = "H:\\Workspace\\VMP\\adjusted_place";
	argus[6] = "1";*/
 	int interval, swap_limit;
	stringstream sin1, sin2;
	for (i = 1; i < argc; i++)
	{
		argus[i - 1] = argv[i];
	}
	sin1 << argus[3];
	sin1 >> interval;
	//cout << "Routing interval: " << interval << endl;
	sin2 << argus[6];
	sin2 >> swap_limit;
	cout << "SWAP limit: " << swap_limit << endl;
	Routing_topo *topo = new Routing_topo();
	topo->construct(argus[0]);
	//cout << 0;
	topo->vm_flow_construct(argus[2]);
	//cout << 2;
	topo->capacity_construct(argus[0]);
	//cout << 0;
	VMTable vmtable;
	vmtable.clear();
	//vmtable.set_swap_limit(swap_limit);
	vmtable.construct(topo, argus[1], argus[2]);
	vmtable.set_swap_limit(swap_limit / 2 + 1);
	//vmtable.vm_place(argus[4]);
	vmtable.vm_random_place();
	vmtable.output_vm(argus[4]);
	//cout << 4;
	int ipa = vmtable.partitionTree();
	int swap = 0;
	int succ = 0;
	int rttm = 0;
	vmtable.put_to_topology();
	vmtable.route();
	while (ipa > 0)// && swap <= swap_limit)
	{
		ipa = vmtable.adjust(succ);
		//if (succ >= interval)
		{
			//vmtable.route();
			swap += succ;
			//cout << "level: " << ipa << endl;
			//cout << swap << endl;
			succ = 0;
			rttm++;
		}
	}
	//vmtable.route();
	vmtable.output();
	vmtable.output_vm(argus[5]);
	cout << "total swap: " << swap << endl;
	//cout << "total route time: " << rttm << endl;
	//system("pause");
	return 0;
}